import pyautogui
from collections import namedtuple

pyautogui.PAUSE=1
pyautogui.FAILSAFE=True

Box=namedtuple('Box',"left top width height")

class LocateExcetion(Exception):
    def __init__(self,msg,liked, *args: object) -> None:
        super().__init__(*args)
        self.message=msg
        self.liked=liked

def box_to_point(box:Box):
    x=box.left+box.width//2
    y=box.top+box.height//2
    return (x,y)

def locate_entries():
    return list(box_to_point(box) for box in pyautogui.locateAllOnScreen('./target/entry.png'))

def locate_entry():
    return box_to_point(pyautogui.locateOnScreen('./target/entry.png'))

def click_on_point(point):
    x,y=point
    pyautogui.click(x,y)

def locate_like():
    box=pyautogui.locateOnScreen('./target/like.png')
    return box_to_point(box) if box else None

previous_entry_point=(200,200)

def do_like(like_count,liked,retry=5,progress_callback=None):
    global previous_entry_point
        
    entries=locate_entries()
    if not entries:
        if previous_entry_point and retry > 0:
            print('没有发现入口按钮，继续尝试中...')
            pyautogui.moveTo(*previous_entry_point)
            scroll_down(-600)
            do_like(like_count,liked,retry-1)
        else:
            raise LocateExcetion('Can not locate target of entry!',liked)
    for entry_point in entries:
        previous_entry_point=entry_point
        click_on_point(entry_point)
        like_point=locate_like()
        if not like_point:
            # print('No like button at',entry_point)
            continue
        click_on_point(like_point)
        liked+=1
        # print('Like successfully, current liked:',liked,like_count)
        if progress_callback:
            progress_callback(liked,like_count)
        if liked>=like_count:
            # print('Task completed!')
            return

    scroll_down(-600)
    do_like(like_count,liked,5,progress_callback=progress_callback)
    


def scroll_down(distance,point=None):
    if point:
        pyautogui.moveTo(*point)
    pyautogui.scroll(distance)




if __name__ == '__main__':
    # for box in locate_entries():
    #     click_on_box(box)
    #     like_box=locate_like()
    #     if not like_box:
    #         continue
    #     click_on_box(like_box)
    #     break
    do_like(5,0)